#include "risk/risk_manager.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include <cmath>
#include <nlohmann/json.hpp>

namespace hft {

RiskManager::RiskManager(const RiskConfig& config) : config_(config) {
}

bool RiskManager::loadConfig(const std::string& config_file) {
    try {
        std::ifstream file(config_file);
        if (!file.is_open()) {
            std::cerr << "无法打开风控配置文件: " << config_file << std::endl;
            return false;
        }
        
        nlohmann::json json_config;
        file >> json_config;
        
        // 解析全局风控限制
        auto& global = json_config["global_limits"];
        config_.global_limits.max_position_value = global["max_position_value"].get<double>();
        config_.global_limits.max_daily_loss = global["max_daily_loss"].get<double>();
        config_.global_limits.max_leverage = global["max_leverage"].get<double>();
        config_.global_limits.max_order_size = global["max_order_size"].get<int>();
        config_.global_limits.max_daily_orders = global["max_daily_orders"].get<int>();
        config_.global_limits.max_order_value = global["max_order_value"].get<double>();
        config_.global_limits.max_position_concentration = global["max_position_concentration"].get<double>();
        
        // 解析合约风控限制
        auto& contracts = json_config["contract_limits"];
        for (auto it = contracts.begin(); it != contracts.end(); ++it) {
            std::string symbol = it.key();
            ContractRiskLimits limits;
            limits.max_position_value = it.value()["max_position_value"].get<double>();
            limits.max_daily_loss = it.value()["max_daily_loss"].get<double>();
            limits.max_leverage = it.value()["max_leverage"].get<double>();
            limits.max_order_size = it.value()["max_order_size"].get<int>();
            limits.max_daily_orders = it.value()["max_daily_orders"].get<int>();
            limits.max_order_value = it.value()["max_order_value"].get<double>();
            limits.price_limit_percent = it.value()["price_limit_percent"].get<double>();
            
            config_.contract_limits[symbol] = limits;
        }
        
        return true;
    } catch (const std::exception& e) {
        std::cerr << "加载风控配置失败: " << e.what() << std::endl;
        return false;
    }
}

bool RiskManager::saveConfig(const std::string& config_file) {
    try {
        nlohmann::json json_config;
        
        // 保存全局风控限制
        auto& global = json_config["global_limits"];
        global["max_position_value"] = config_.global_limits.max_position_value;
        global["max_daily_loss"] = config_.global_limits.max_daily_loss;
        global["max_leverage"] = config_.global_limits.max_leverage;
        global["max_order_size"] = config_.global_limits.max_order_size;
        global["max_daily_orders"] = config_.global_limits.max_daily_orders;
        global["max_order_value"] = config_.global_limits.max_order_value;
        global["max_position_concentration"] = config_.global_limits.max_position_concentration;
        
        // 保存合约风控限制
        auto& contracts = json_config["contract_limits"];
        for (const auto& [symbol, limits] : config_.contract_limits) {
            contracts[symbol]["max_position_value"] = limits.max_position_value;
            contracts[symbol]["max_daily_loss"] = limits.max_daily_loss;
            contracts[symbol]["max_leverage"] = limits.max_leverage;
            contracts[symbol]["max_order_size"] = limits.max_order_size;
            contracts[symbol]["max_daily_orders"] = limits.max_daily_orders;
            contracts[symbol]["max_order_value"] = limits.max_order_value;
            contracts[symbol]["price_limit_percent"] = limits.price_limit_percent;
        }
        
        std::ofstream file(config_file);
        if (!file.is_open()) {
            std::cerr << "无法打开风控配置文件: " << config_file << std::endl;
            return false;
        }
        
        file << json_config.dump(4);
        return true;
    } catch (const std::exception& e) {
        std::cerr << "保存风控配置失败: " << e.what() << std::endl;
        return false;
    }
}

RiskCheckResult RiskManager::checkOrder(const Order& order) {
    // 检查全局风控限制
    auto global_result = checkGlobalLimits(order);
    if (!global_result.passed) {
        return global_result;
    }
    
    // 检查合约风控限制
    auto contract_result = checkContractLimits(order);
    if (!contract_result.passed) {
        return contract_result;
    }
    
    // 检查账户风控限制
    auto account_result = checkAccountLimits(order);
    if (!account_result.passed) {
        return account_result;
    }
    
    return {true, ""};
}

RiskCheckResult RiskManager::checkPosition(const Position& position) {
    RiskCheckResult result{true, ""};
    
    // 检查持仓市值
    if (config_.global_limits.max_position_value > 0 && 
        position.position_value > config_.global_limits.max_position_value) {
        result.passed = false;
        result.reason = "持仓市值超过全局限制";
        return result;
    }
    
    // 检查合约持仓市值
    auto it = config_.contract_limits.find(position.symbol);
    if (it != config_.contract_limits.end() && 
        it->second.max_position_value > 0 && 
        position.position_value > it->second.max_position_value) {
        result.passed = false;
        result.reason = "持仓市值超过合约限制";
        return result;
    }
    
    // 检查杠杆率
    if (config_.global_limits.max_leverage > 0 && 
        position.leverage > config_.global_limits.max_leverage) {
        result.passed = false;
        result.reason = "杠杆率超过全局限制";
        return result;
    }
    
    // 检查合约杠杆率
    if (it != config_.contract_limits.end() && 
        it->second.max_leverage > 0 && 
        position.leverage > it->second.max_leverage) {
        result.passed = false;
        result.reason = "杠杆率超过合约限制";
        return result;
    }
    
    return result;
}

void RiskManager::setAccountBalance(const std::string& account, double balance) {
    account_balances_[account] = balance;
}

void RiskManager::setContractPrice(const std::string& symbol, double price) {
    contract_prices_[symbol] = price;
}

void RiskManager::updateDailyStats(const Trade& trade) {
    // 更新日订单数量
    daily_order_counts_[trade.account]++;
    
    // 更新日亏损
    if (trade.side == OrderSide::Sell) {
        // 卖出时，如果价格低于当前价格，则产生亏损
        auto it = contract_prices_.find(trade.symbol);
        if (it != contract_prices_.end() && trade.price < it->second) {
            double loss = (it->second - trade.price) * trade.volume;
            daily_losses_[trade.account] += loss;
        }
    } else {
        // 买入时，如果价格高于当前价格，则产生亏损
        auto it = contract_prices_.find(trade.symbol);
        if (it != contract_prices_.end() && trade.price > it->second) {
            double loss = (trade.price - it->second) * trade.volume;
            daily_losses_[trade.account] += loss;
        }
    }
}

void RiskManager::resetDailyStats() {
    daily_order_counts_.clear();
    daily_losses_.clear();
}

const RiskConfig& RiskManager::getConfig() const {
    return config_;
}

void RiskManager::updateConfig(const RiskConfig& config) {
    config_ = config;
}

RiskCheckResult RiskManager::checkGlobalLimits(const Order& order) {
    RiskCheckResult result{true, ""};
    
    // 检查订单数量
    if (config_.global_limits.max_order_size > 0 && 
        order.volume > config_.global_limits.max_order_size) {
        result.passed = false;
        result.reason = "订单数量超过全局限制";
        return result;
    }
    
    // 检查日订单数量
    if (config_.global_limits.max_daily_orders > 0 && 
        daily_order_counts_[order.account] >= config_.global_limits.max_daily_orders) {
        result.passed = false;
        result.reason = "日订单数量超过全局限制";
        return result;
    }
    
    // 检查订单金额
    double order_value = calculateOrderValue(order);
    if (config_.global_limits.max_order_value > 0 && 
        order_value > config_.global_limits.max_order_value) {
        result.passed = false;
        result.reason = "订单金额超过全局限制";
        return result;
    }
    
    // 检查日亏损
    if (config_.global_limits.max_daily_loss > 0 && 
        daily_losses_[order.account] >= config_.global_limits.max_daily_loss) {
        result.passed = false;
        result.reason = "日亏损超过全局限制";
        return result;
    }
    
    return result;
}

RiskCheckResult RiskManager::checkContractLimits(const Order& order) {
    RiskCheckResult result{true, ""};
    
    auto it = config_.contract_limits.find(order.symbol);
    if (it == config_.contract_limits.end()) {
        return result;
    }
    
    const auto& limits = it->second;
    
    // 检查订单数量
    if (limits.max_order_size > 0 && 
        order.volume > limits.max_order_size) {
        result.passed = false;
        result.reason = "订单数量超过合约限制";
        return result;
    }
    
    // 检查订单金额
    double order_value = calculateOrderValue(order);
    if (limits.max_order_value > 0 && 
        order_value > limits.max_order_value) {
        result.passed = false;
        result.reason = "订单金额超过合约限制";
        return result;
    }
    
    // 检查价格涨跌幅
    if (limits.price_limit_percent > 0) {
        auto price_it = contract_prices_.find(order.symbol);
        if (price_it != contract_prices_.end()) {
            double base_price = price_it->second;
            double upper_limit = base_price * (1 + limits.price_limit_percent);
            double lower_limit = base_price * (1 - limits.price_limit_percent);
            
            if (order.price > upper_limit || order.price < lower_limit) {
                result.passed = false;
                result.reason = "订单价格超过涨跌幅限制";
                return result;
            }
        }
    }
    
    return result;
}

RiskCheckResult RiskManager::checkAccountLimits(const Order& order) {
    RiskCheckResult result{true, ""};
    
    // 检查账户余额
    auto it = account_balances_.find(order.account);
    if (it != account_balances_.end()) {
        double order_value = calculateOrderValue(order);
        double required_margin = order_value * 0.1; // 假设保证金率为10%
        
        if (it->second < required_margin) {
            result.passed = false;
            result.reason = "账户余额不足";
            return result;
        }
    }
    
    return result;
}

double RiskManager::calculateOrderValue(const Order& order) {
    double price = order.price;
    if (price <= 0) {
        auto it = contract_prices_.find(order.symbol);
        if (it != contract_prices_.end()) {
            price = it->second;
        } else {
            return 0.0;
        }
    }
    
    return price * order.volume;
}

} // namespace hft